/* TEAM AWESOMES
 * -Kylan
 * -Leonardo
 * -Anthony
 *
 * relrecv receives a file from the relsend program
 */

#include "basics.h"

///////////////GLOBAL CONSTANTS////////////////

#define DEBUG 1
#define BUFSIZE 1200
#define error(s) { perror(s); exit(1); }

//////////////DECLARE GLOBAL VARS//////////////

int sock; // send and receive socket
int port; // receiver port number

//////////////DECLARE DEFINITIONS//////////////

void parseCommandLine(int argc, char**argv);
void createSocket();
void receiveFile();

int main(int argc, char**argv) {
    parseCommandLine(argc, argv);
    createSocket();
    receivePackets();
}

void receivePackets() {
  int addr_len, bytesRead;
  unsigned char recvData[BUFSIZE];
  struct sockaddr_in client_addr;

  addr_len = sizeof (struct sockaddr);

  while(1) {
    memset(recvData, 0, BUFSIZE);
    bytesRead = recvfrom(sock, recvData, BUFSIZE, 0, (struct sockaddr *) &client_addr, &addr_len);

    //Print out who we're receiving from and what we're receiving.
    printf("Receiving data from %s : %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

    //A control packet
    if(recvData[0] == 204) {
      //SYN packet
      if(recvData[1] == 170) {
	printf("It's a SYN packet.\n\n\n");
	//receiveSYN();
      }
      //FIN packet
      else if(recvData[1] == 238) {
	printf("It's a FIN packet.\n\n\n");
	exit(0);
      }
    }
    //data packet
    else { //if(recvData[0] == 221)
      printf("It's a data packet.\n\n\n");
      receiveFile(recvData, bytesRead);
    }
  }
}

void receiveFile(char * recvData, int bytesRead) {

    printf("\nWaiting for data on port %d\n", port);
    
    FILE *fp;
    fp=fopen("dummyfile.txt", "ab");
    
    int x;
    for(x = 0; x < bytesRead; x++) {
      fputc(recvData[x], fp);
    }
    
    fclose(fp);
    
}


void parseCommandLine(int argc, char**argv) {

    // Validate number of arguments
    if (argc != 2) {
        printf("Invalid arguments, use format: ./relrecv <port>\n");
        exit(1);
    }

    // Validate port number
    int tempPort;
    if(tempPort = atoi(argv[1])) {
        //Check port range
        if(tempPort < 1025 || tempPort > 65535) {
            printf("Invalid port, port must be in range 1025-65535.\n");
            exit(1);
        }
        else {
            port = tempPort;
            if(DEBUG) { printf("Port: %d\n", port); }
        }
    }
    else { // check if atoi passed
        printf("Invalid port: port must be a number.\n");
        exit(1);
    }
    
}

void createSocket() {

    struct sockaddr_in server_addr;

    // Generate the socket
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("Socket");
        exit(1);
    }

    // Set up struct to receive data from our port and address
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    bzero(&(server_addr.sin_zero), 8);

    // Bind the struct to our socket
    if (bind(sock, (struct sockaddr *) &server_addr,
            sizeof (struct sockaddr)) == -1) {
        perror("Bind");
        exit(1);
    }

}
